#include <iostream>
#include <cstring>
using namespace std;

int main(int argc, char const *argv[])
{
    int n;    // n个物品
    cin >> n;

    int w[n+1]; // 每个物品的重量
    int v[n+1]; // 每个物品的价值

    for(int i=1; i<=n; i++)
        cin >> w[i];

    for(int i=1; i<=n; i++)
        cin >> v[i];

    // 背包的容量
    int b;
    cin >> b;

    // 优化函数数组
    int F[n+1][b+1];

    // 优化函数 - 初始条件
    int k; // 代表物品数量从 1 - n 变化
    int y; // 代表背包容量从 1 - b 变化

    for(y=1; y<=b; y++)
        F[0][y] = 0;

    for(k=1; k<=n; k++)
        F[k][0] = 0;

    for(y=1; y<=b; y++)
        F[1][y] = (y/w[1]) * v[1];


    // 标记函数数组
    // i[k][y]: 取前面的k个物品，背包容量为y时最大的物品编号
    int i[n+1][b+1];

    // 标记函数 - 初始条件
    for(y=1; y<=b; y++)
    {
        // 背包容量小于第一个物品的重量，无法装下任何物品
        if(y < w[1])
            i[1][y] = 0;
        
        // 背包容量大于等于第一个物品的重量，装下的最大物品的编号就是1
        if(y >= w[1])
            i[1][y] = 1;
    }


    int maxValue = 0;
    for(k=2; k<=n; k++)
    {
        for(y=1; y<=b; y++)
        {
            // 优化函数的递推
            if(y < w[k])
                F[k][y] = F[k-1][y];
            else
                F[k][y] = max(F[k-1][y], F[k][y-w[k]]+v[k]);

            maxValue = maxValue>F[k][y] ? maxValue : F[k][y];


            // 标记函数的递推
            if(F[k-1][y] > F[k][y-w[k]]+v[k])
                i[k][y] = i[k-1][y];
            else if(F[k-1][y] <= F[k][y-w[k]]+v[k])
                i[k][y] = k;
        }
    }

    cout << "优化函数" << endl;
    for(int ii=1; ii<=n; ii++)
    {
        for(int jj=1; jj<=b; jj++)
        {
            printf("%d\t", F[ii][jj]);
        }
        printf("\n");
    }

    cout << "标记函数" << endl;
    for(int ii=1; ii<=n; ii++)
    {
        for(int jj=1; jj<=b; jj++)
        {
            printf("%d\t", i[ii][jj]);
        }
        printf("\n");
    }
    cout << "最大价值:" << maxValue << endl;


    // 第i个物品的个数有x[i]个
    int x[n+1];
    bzero(x, sizeof(x));

    int j;
    y = b;
    j = n;

    while(1)
    {
        // 查标记函数的表，得到最大物品的编号
        j = i[j][y];

        // 第j个物品至少有1个
        x[j] = 1;

        // 背包容量随着装入的物品递减
        y -= w[j];
        while(i[j][y] == j)
        {
            y -= w[j];
            x[j]++;
        }

        if(i[j][y] == 0)
            break;
    }

    for(int i=1; i<=n; i++)
        printf("第%d个物品：%d个\n", i, x[i]);

    // 第1个物品：0个
    // 第2个物品：1个
    // 第3个物品：0个
    // 第4个物品：1个

    return 0;
}
